home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
bsvc-1.000
/
bsvc-1
/
bsvc-1.0.4
/
src
/
SimHector
/
cpu
/
exec.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-26
|
81KB
|
2,580 lines
///////////////////////////////////////////////////////////////////////////////
//
// File: exec.cxx (Part of the ControlUnit Class)
//
// Purpose: This module contains the instruction execution
// functions. Each function does address mode decoding
// where necessary and then calls the appropriate
// register transfer functions to execute the
// instruction. The comments above each register
// transfer function call are the actual HECTOR
// microcode instructions performed.
//
// NOTE: Because these instructions follow the micro-
// code, they also depend on such things as the fact
// that in single operand instructions like SWAP the
// SRC and DST fields in the instruction both contain
// the operand register
//
// Author: Greg DeHoogh
//
// Modified: Bradford W. Mott (BSVC version)
//
// History: 17 February 1990 - Creation
//
// 18 April 1990 - fixed bug in group1, source mode
// indexed, destination mode postincrement - GLD
//
// 24 April 1990 - fixed bug in move, source and
// destination modes indexed; and in group1, source
// mode indirect and desination mode postincrement
// - GLD
//
// 04 December 1993 - Modified to work with the new
// BSVC version of the Hector simulator
//
///////////////////////////////////////////////////////////////////////////////
#include "Tools.hxx"
#include "ControlUnit.hxx"
///////////////////////////////////////////////////////////////////////////////
// Addressing Modes
///////////////////////////////////////////////////////////////////////////////
const unsigned int REG=0; // Register Direct
const unsigned int IND=1; // Register Indirect
const unsigned int ABS=1; // Absolute (used by BRA and JSR)
const unsigned int INC=2; // Register Indirect with postincrement
const unsigned int REL=2; // Program Counter Relative (BRA and JSR)
const unsigned int NDX=3; // Indexed
///////////////////////////////////////////////////////////////////////////////
// group1 - ADD, ADDC, SUB, AND, SUBC, OR, and XOR
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteGroup1(int trace_flag)
{
int DM = (data_path.ir & 0x0300) >> 8;
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir &0x00f0) >> 4;
int DST = (data_path.ir &0x000f);
const char* error_message;
unsigned int src_index, dst_index;
switch(DM)
{
case REG: switch(SM) {
case REG: // OP Rsrc,Rdst
// dst < dst OP src
if((error_message = reg_op_reg_to_reg(SRC, DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // OP [Rsrc],Rdst
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// dst < dst OP t1
if((error_message = reg_op_reg_to_reg(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // OP [Rsrc+],Rdst
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// dst < dst OP t1
if((error_message = reg_op_reg_to_reg(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // OP [Rsrc,index],Rdst
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index to put in trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// dst < dst OP t1
if((error_message = reg_op_reg_to_reg(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
break;
}
if(trace_flag)
{
mnemonic+=",";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
}
break;
case IND: switch (SM) {
case REG: // OP Rsrc,[Rdst]
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < t2 OP src
if((error_message = reg_op_reg_to_mdr(SRC, T2)) != (void*)0)
return(error_message);
// (mar) < mdr
if((error_message = mdr_to_mar_indirect()) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // OP [Rsrc],[Rdst]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < t2 OP t1
if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
return(error_message);
// (mar) < mdr
if((error_message = mdr_to_mar_indirect()) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // OP [Rsrc+],[Rdst]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < t2 OP t1
if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
return(error_message);
// (mar) < mdr */
if((error_message = mdr_to_mar_indirect()) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // OP [Rsrc,index],[Rdst]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index to put the in the trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < t2 * t1
if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
return(error_message);
// (mar) < mdr
if((error_message = mdr_to_mar_indirect()) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
break;
}
if(trace_flag)
{
mnemonic+=",[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="]";
}
break;
case INC: switch (SM) {
case REG: // OP Rsrc,[Rdst+]
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < t2 OP src
if((error_message = reg_op_reg_to_mdr(SRC, T2)) != (void*)0)
return(error_message);
// (mar) < mdr; dst < dst + 1
if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // OP [Rsrc],[Rdst+]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < t2 OP t1
if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
return(error_message);
// (mar) < mdr; dst < dst + 1
if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // OP [Rsrc+],[Rdst+]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < t2 OP t1
if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
return(error_message);
// (mar) < mdr; dst < dst + 1
if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // OP [Rsrc,index],[Rdst+]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index to put the in the trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < t2 OP t1
if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
return(error_message);
// (mar) < mdr; dst < dst + 1
if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
break;
}
if(trace_flag)
{
mnemonic+=",[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="+]";
}
break;
case NDX: switch (SM) {
case REG: // OP Rsrc,[Rdst,index]
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save index value to build trace record with
dst_index=data_path.register_set.GetRegister(T2);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// mdr < t2 OP src
if((error_message = reg_op_reg_to_mdr(SRC, T2)) != (void*)0)
return(error_message);
// (mar) < mdr; pc < pc + 1
if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // OP [Rsrc],[Rdst,index]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save index value to build trace record with
dst_index=data_path.register_set.GetRegister(T2);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// mdr < t2 OP t1
if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
return(error_message);
// (mar) < mdr; pc < pc + 1
if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // OP [Rsrc+],[Rdst,index]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save index value to build trace record with
dst_index=data_path.register_set.GetRegister(T2);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// mdr < t2 OP t1
if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
return(error_message);
// (mar) < mdr; pc < pc + 1
if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // OP [Rsrc,index],[Rdst,index]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save index value to build trace record with
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save index value to build trace record with
dst_index=data_path.register_set.GetRegister(T2);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// mdr < t2 OP t1
if((error_message = reg_op_reg_to_mdr(T1, T2)) != (void*)0)
return(error_message);
// (mar) < mdr; pc < pc + 1
if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
break;
}
if(trace_flag)
{
mnemonic+=",[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+=",$";
mnemonic+=IntToString(dst_index, 4);
mnemonic+="]";
}
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// group2 - NOT, NEG, INC, DEC, SHL, ROL, SHR, and ROR
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteGroup2(int trace_flag)
{
int SM = (data_path.ir & 0x0c00) >> 10;
int DST = data_path.ir &0x000f;
const char* error_message;
unsigned int dst_index;
switch(SM) {
case REG: // OP Rdst
// dst < OP dst
if((error_message = op_reg_to_reg(DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
break;
case IND: // OP [Rdst]
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < OP t2
if((error_message = op_reg_to_mdr(T2)) != (void*)0)
return(error_message);
// (mar) < mdr
if((error_message = mdr_to_mar_indirect()) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="]";
}
break;
case INC: // OP [Rdst+]
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < OP t2
if((error_message = op_reg_to_mdr(T2)) != (void*)0)
return(error_message);
// (mar) < mdr; dst < dst + 1
if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="+]";
}
break;
case NDX: // OP [Rdst,index]
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save the index for the trace record
dst_index=data_path.register_set.GetRegister(T2);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// mdr < OP t2
if((error_message = op_reg_to_mdr(T2)) != (void*)0)
return(error_message);
// (mar) < mdr; pc < pc + 1
if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+=",$";
mnemonic+=IntToString(dst_index, 4);
mnemonic+="]";
}
break;
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// group3 - CMP and BTST
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteGroup3(int trace_flag)
{
int DM = (data_path.ir & 0x0300) >> 8;
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir &0x00f0) >> 4;
int DST = (data_path.ir &0x000f);
const char* error_message;
unsigned int src_index, dst_index;
switch(DM) {
case REG: switch(SM) {
case REG: // OP Rsrc,Rdst
// dst OP src
if((error_message = reg_op_reg(SRC, DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // OP [Rsrc],Rdst
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// dst OP t1
if((error_message = reg_op_reg(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // OP [Rsrc+],Rdst
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// dst OP t1
if((error_message = reg_op_reg(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // OP [Rsrc,index],Rdst
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save index for trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// dst OP t1
if((error_message = reg_op_reg(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
break;
}
if(trace_flag)
{
mnemonic+=",";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
}
break;
case IND: switch (SM) {
case REG: // OP Rsrc,[Rdst]
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// t2 OP src
if((error_message = reg_op_reg(SRC, T2)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // OP [Rsrc],[Rdst]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// t2 OP t1
if((error_message = reg_op_reg(T1, T2)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // OP [Rsrc+],[Rdst]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// t2 OP t1
if((error_message = reg_op_reg(T1, T2)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // OP [Rsrc,index],[Rdst]
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index for the trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// t2 OP t1
if((error_message = reg_op_reg(T1, T2)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
break;
}
if(trace_flag)
{
mnemonic+=",[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="]";
}
break;
case INC: switch (SM) {
case REG: // OP Rsrc,[Rdst+]
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// dst < dst + 1
if((error_message = inc_reg(DST)) != (void*)0)
return(error_message);
// t2 OP src
if((error_message = reg_op_reg(SRC, T2)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // OP [Rsrc],[Rdst+]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// dst < dst + 1
if((error_message = inc_reg(DST)) != (void*)0)
return(error_message);
// t2 OP t1
if((error_message = reg_op_reg(T1, T2)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // OP [Rsrc+],[Rdst+]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// dst < dst + 1
if((error_message = inc_reg(DST)) != (void*)0)
return(error_message);
// t2 OP t1
if((error_message = reg_op_reg(T1, T2)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // OP [Rsrc,index],[Rdst+]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index for the trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mar < t1 + src */
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// dst < dst + 1
if((error_message = inc_reg(DST)) != (void*)0)
return(error_message);
// t2 OP t1
if((error_message = reg_op_reg(T1, T2)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
break;
}
if(trace_flag)
{
mnemonic+=",[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="+]";
}
break;
case NDX: switch (SM) {
case REG: // OP Rsrc,[Rdst,index]
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save the index for the trace record
dst_index=data_path.register_set.GetRegister(T2);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// t2 OP src
if((error_message = reg_op_reg(SRC, T2)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // OP [Rsrc],[Rdst,index]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save the index for the trace record
dst_index=data_path.register_set.GetRegister(T2);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// t2 OP t1
if((error_message = reg_op_reg(T1, T2)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // OP [Rsrc+],[Rdst,index]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save the index for the trace record
dst_index=data_path.register_set.GetRegister(T2);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// t2 OP t1
if((error_message = reg_op_reg(T1, T2)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // OP [Rsrc,index],[Rdst,index]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index for the trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save the index for the trace record
dst_index=data_path.register_set.GetRegister(T2);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// t2 OP t1
if((error_message = reg_op_reg(T1, T2)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
}
if(trace_flag)
{
mnemonic+=",[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+=",$";
mnemonic+=IntToString(dst_index, 4);
mnemonic+="]";
}
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// branch - BRA
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteBRA(int trace_flag)
{
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir &0x00f0) >> 4;
ALUConditionCode CC = (data_path.ir &0x000f);
const char* error_message;
const char* cc_description;
unsigned int index;
switch (SM) {
case REG: // BRA Rsrc
// t1 < src
if((error_message = reg_to_reg(SRC, T1)) != (void*)0)
return(error_message);
if(data_path.alu.TestConditionCode(CC, cc_description))
{
// pc < t1
if((error_message = reg_to_reg(T1, PC)) != (void*)0)
return(error_message);
}
else
{
data_path.Clock();
}
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case ABS: // BRA @destination
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
if(data_path.alu.TestConditionCode(CC, cc_description))
{
// pc < t1
if((error_message = reg_to_reg(T1, PC)) != (void*)0)
return(error_message);
}
else
{
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
}
if(trace_flag)
{
mnemonic+="@$";
mnemonic+=IntToString(data_path.register_set.GetRegister(T1), 4);
}
break;
case REL: // BRA destination
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
if(data_path.alu.TestConditionCode(CC, cc_description))
{
// pc < pc + t1
if((error_message = reg_plus_reg_to_reg(T1, PC)) != (void*)0)
return(error_message);
}
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="$";
mnemonic+=IntToString(data_path.register_set.GetRegister(T1), 4);
}
break;
case NDX: // BRA [Rsrc,base_destination]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save index for trace register
index=data_path.register_set.GetRegister(T1);
if(data_path.alu.TestConditionCode(CC, cc_description))
{
// t1 < t1 + src
if((error_message = reg_plus_reg_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// pc < (t1)
if((error_message = reg_indirect_to_reg(T1, PC)) != (void*)0)
return(error_message);
}
else
{
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
}
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(index, 4);
mnemonic+="]";
}
}
if(trace_flag)
{
mnemonic+=",";
mnemonic+=cc_description;
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// JSR
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteJSR(int trace_flag)
{
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir &0x00f0) >> 4;
ALUConditionCode CC = (data_path.ir &0x000f);
const char* error_message;
const char* cc_description;
unsigned int index;
switch (SM) {
case REG: // JSR Rsrc
// t1 < src
if((error_message = reg_to_reg(SRC, T1)) != (void*)0)
return(error_message);
if(data_path.alu.TestConditionCode(CC, cc_description))
{
// sp < sp - 1
if((error_message = dec_reg(SP)) != (void*)0)
return(error_message);
// (sp) < pc
if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
return(error_message);
// pc < t1
if((error_message = reg_to_reg(T1, PC)) != (void*)0)
return(error_message);
}
else
{
data_path.Clock();
}
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case ABS: // JSR @location
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
if(data_path.alu.TestConditionCode(CC, cc_description))
{
// sp < sp - 1
if((error_message = dec_reg(SP)) != (void*)0)
return(error_message);
// (sp) < pc
if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
return(error_message);
// pc < t1
if((error_message = reg_to_reg(T1, PC)) != (void*)0)
return(error_message);
}
if(trace_flag)
{
mnemonic+="@$";
mnemonic+=IntToString(data_path.register_set.GetRegister(T1), 4);
}
break;
case REL: // JSR location
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
if(data_path.alu.TestConditionCode(CC, cc_description))
{
// sp < sp - 1
if((error_message = dec_reg(SP)) != (void*)0)
return(error_message);
// (sp) < pc
if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
return(error_message);
// pc < pc + t1
if((error_message = reg_plus_reg_to_reg(T1, PC)) != (void*)0)
return(error_message);
}
if(trace_flag)
{
mnemonic+="$";
mnemonic+=IntToString(data_path.register_set.GetRegister(T1), 4);
}
break;
case NDX: // JSR [Rsrc,base_address]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save index for trace register
index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
if(data_path.alu.TestConditionCode(CC, cc_description))
{
// sp < sp - 1
if((error_message = dec_reg(SP)) != (void*)0)
return(error_message);
// (sp) < pc
if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
return(error_message);
// t1 < t1 + src
if((error_message = reg_plus_reg_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// pc < (t1)
if((error_message = reg_indirect_to_reg(T1, PC)) != (void*)0)
return(error_message);
}
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(index, 4);
mnemonic+="]";
}
}
if(trace_flag)
{
mnemonic+=",";
mnemonic+=cc_description;
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// swap - SWAP
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteSWAP(int trace_flag)
{
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir &0x00f0) >> 4;
int DST = (data_path.ir &0x000f);
const char* error_message;
unsigned int index;
switch (SM) {
case REG: // SWAP Rsrc
// dst < *swap[src]
if((error_message = swap_reg_to_reg(SRC, DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // SWAP [Rsrc]
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < *swap[t2]
if((error_message = swap_reg_to_mdr(T2)) != (void*)0)
return(error_message);
// (mar) < mdr
if((error_message = mdr_to_mar_indirect()) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // SWAP [Rsrc+]
// t2 < (dst)
if((error_message = reg_indirect_to_reg(DST, T2)) != (void*)0)
return(error_message);
// mdr < *swap[t2]
if((error_message = swap_reg_to_mdr(T2)) != (void*)0)
return(error_message);
// (mar) < mdr; dst < dst + 1
if((error_message = mdr_to_mar_indirect_with_inc(DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // SWAP [Rsrc,index]
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save index for trace register
index=data_path.register_set.GetRegister(T2);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// t2 < (mar)
if((error_message = mar_indirect_to_reg(T2)) != (void*)0)
return(error_message);
// mdr < *swap[t2]
if((error_message = swap_reg_to_mdr(T2)) != (void*)0)
return(error_message);
// (mar) < mdr; pc < pc + 1
if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(index, 4);
mnemonic+="]";
}
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// clear - CLR
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteCLR(int trace_flag)
{
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir &0x00f0) >> 4;
int DST = (data_path.ir &0x000f);
const char* error_message;
unsigned int index;
switch (SM) {
case REG: // CLR Rdst
// dst < 0
if((error_message = clr_reg(DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
break;
case IND: // CLR [Rdst]
// t1 < 0
if((error_message = clr_reg(T1)) != (void*)0)
return(error_message);
// (dst) < t1
if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="]";
}
break;
case INC: // CLR [Rdst+]
// t1 < 0
if((error_message = clr_reg(T1)) != (void*)0)
return(error_message);
// (dst) < t1; dst < dst + 1
if((error_message = reg_to_reg_indirect_with_inc(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="+]";
}
break;
case NDX: // CLR [Rdst,index]
// mdr < 0
if((error_message = clr_mdr()) != (void*)0)
return(error_message);
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// (mar) < mdr; pc < pc + 1
if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+=",$";
mnemonic+=IntToString(index, 4);
mnemonic+="]";
}
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// move - MOVE
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteMOVE(int trace_flag)
{
int DM = (data_path.ir & 0x0300) >> 8;
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir & 0x00f0) >> 4;
int DST = (data_path.ir & 0x000f);
const char* error_message;
unsigned int src_index, dst_index;
switch(DM) {
case REG: switch(SM) {
case REG: // MOVE Rsrc,Rdst
// dst < src
if((error_message = reg_to_reg(SRC, DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // MOVE [Rsrc],Rdst
// dst < (src)
if((error_message = reg_indirect_to_reg(SRC, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // MOVE [Rsrc+],Rdst
// dst < (src)
if((error_message = reg_indirect_to_reg(SRC, DST)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // MOVE [Rsrc,index],Rdst
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index for the trace record
src_index=data_path.register_set.GetRegister(T1);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// dst < (mar)
if((error_message = mar_indirect_to_reg(DST)) != (void*)0)
return(error_message);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
}
if(trace_flag)
{
mnemonic+=",";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
}
break;
case IND: switch (SM) {
case REG: // MOVE Rsrc,[Rdst]
// (dst) < src
if((error_message = reg_to_reg_indirect(SRC, DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // MOVE [Rsrc],[Rdst]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// (dst) < t1
if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // MOVE [Rsrc+],[Rdst]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// (dst) < t1
if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // MOVE [Rsrc,index],[Rdst]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index for the trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// (dst) < t1
if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
}
if(trace_flag)
{
mnemonic+=",[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="]";
}
break;
case INC: switch (SM) {
case REG: // MOVE Rsrc,[Rdst+]
// (dst) < src; dst < dst + 1
if((error_message=reg_to_reg_indirect_with_inc(SRC, DST))!=(void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // MOVE [Rsrc],[Rdst+]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// (dst) < t1; dst < dst + 1
if((error_message = reg_to_reg_indirect_with_inc(T1, DST))!=(void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // MOVE [Rsrc+],[Rdst+]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// (dst) < t1; dst < dst + 1
if((error_message=reg_to_reg_indirect_with_inc(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // MOVE [Rsrc,index],[Rdst+]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index for the trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// (dst) < t1; dst < dst + 1
if((error_message=reg_to_reg_indirect_with_inc(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
break;
}
if(trace_flag)
{
mnemonic+=",[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="+]";
}
break;
case NDX: switch (SM) {
case REG: // MOVE Rsrc,[Rdst,index]
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save the index for the trace record
dst_index=data_path.register_set.GetRegister(T2);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// (mar) < src
if((error_message = reg_to_mar_indirect(SRC)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // MOVE [Rsrc],[Rdst,index]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save the index for the trace record
dst_index=data_path.register_set.GetRegister(T2);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// (mar) < t1
if((error_message = reg_to_mar_indirect(T1)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // MOVE [Rsrc+],[Rdst,index]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save the index for the trace record
dst_index=data_path.register_set.GetRegister(T2);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// (mar) < t1
if((error_message = reg_to_mar_indirect(T1)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // MOVE [Rsrc,index],[Rdst,index]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index for the trace record
src_index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// t2 < (pc)
if((error_message = reg_indirect_to_reg(PC, T2)) != (void*)0)
return(error_message);
// Save the index for the trace record
dst_index=data_path.register_set.GetRegister(T2);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t2 + dst
if((error_message = reg_plus_reg_to_mar(DST, T2)) != (void*)0)
return(error_message);
// (mar) < t1
if((error_message = reg_to_mar_indirect(T1)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(src_index, 4);
mnemonic+="]";
}
}
if(trace_flag)
{
mnemonic+=",[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+=",$";
mnemonic+=IntToString(dst_index, 4);
mnemonic+="]";
}
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// test - TEST
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteTEST(int trace_flag)
{
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir &0x00f0) >> 4;
const char* error_message;
unsigned int index;
switch (SM) {
case REG: // TEST Rsrc
// t1 < *pass[src]
if((error_message = pass_reg_to_reg(SRC, T1)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // TEST [Rsrc]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// t1 < *pass[t1]
if((error_message = pass_reg_to_reg(T1, T1)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // TEST [Rsrc+]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// t1 < *pass[t1]
if((error_message = pass_reg_to_reg(T1, T1)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // TEST [Rsrc,index]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index for the trace record
index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// t1 < *pass[t1]
if((error_message = pass_reg_to_reg(T1, T1)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(index, 4);
mnemonic+="]";
}
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// store_flags - STF
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteSTF(int trace_flag)
{
int SM = (data_path.ir & 0x0c00) >> 10;
int DST = (data_path.ir &0x000f);
const char* error_message;
unsigned int index;
switch (SM) {
case REG: // STF Rdst
// dst < flags
if((error_message = flags_to_reg(DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
break;
case IND: // STF [Rdst]
// t1 < flags
if((error_message = flags_to_reg(T1)) != (void*)0)
return(error_message);
// (dst) < t1
if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="]";
}
break;
case INC: // STF [Rdst+]
// t1 < flags
if((error_message = flags_to_reg(T1)) != (void*)0)
return(error_message);
// (dst) < t1; dst < dst + 1
if((error_message = reg_to_reg_indirect_with_inc(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+="+]";
}
break;
case NDX: // STF [Rdst,index]
// mdr < flags
if((error_message = flags_to_mdr()) != (void*)0)
return(error_message);
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index to use in the trace record
index=data_path.register_set.GetRegister(T1);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(DST, T1)) != (void*)0)
return(error_message);
// (mar) < mdr; pc < pc + 1
if((error_message = mdr_to_mar_indirect_with_inc(PC)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
mnemonic+=",$";
mnemonic+=IntToString(index, 4);
mnemonic+="]";
}
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// load_flags - LDF
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteLDF(int trace_flag)
{
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir &0x00f0) >> 4;
const char* error_message;
unsigned int index;
switch (SM) {
case REG: // LDF Rsrc
// flags < src
if((error_message = reg_to_flags(SRC)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // LDF [Rsrc]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// flags < t1
if((error_message = reg_to_flags(T1)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // LDF [Rsrc+]
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// flags < t1
if((error_message = reg_to_flags(T1)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // LDF [Rsrc,index]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index to use in the trace record
index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// flags < t1
if((error_message = reg_to_flags(T1)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(index, 4);
mnemonic+="]";
}
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// push - PUSH
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecutePUSH(int trace_flag)
{
int SM = (data_path.ir & 0x0c00) >> 10;
int SRC = (data_path.ir & 0x00f0) >> 4;
int DST = data_path.ir & 0x000f;
const char* error_message;
unsigned int index;
switch (SM) {
case REG: // PUSH Rsrc
// dst < dst - 1
if((error_message = dec_reg(DST)) != (void*)0)
return(error_message);
// (dst) < src
if((error_message = reg_to_reg_indirect(SRC, DST)) != (void*)0)
return(error_message);
if(trace_flag)
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
break;
case IND: // PUSH [Rsrc]
// dst < dst - 1
if((error_message = dec_reg(DST)) != (void*)0)
return(error_message);
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// (dst) < t1
if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="]";
}
break;
case INC: // PUSH [Rsrc+]
// dst < dst - 1
if((error_message = dec_reg(DST)) != (void*)0)
return(error_message);
// t1 < (src)
if((error_message = reg_indirect_to_reg(SRC, T1)) != (void*)0)
return(error_message);
// src < src + 1
if((error_message = inc_reg(SRC)) != (void*)0)
return(error_message);
// (dst) < t1
if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+="+]";
}
break;
case NDX: // PUSH [Rsrc,index]
// t1 < (pc)
if((error_message = reg_indirect_to_reg(PC, T1)) != (void*)0)
return(error_message);
// Save the index to use in the trace record
index=data_path.register_set.GetRegister(T1);
// pc < pc + 1
if((error_message = inc_reg(PC)) != (void*)0)
return(error_message);
// mar < t1 + src
if((error_message = reg_plus_reg_to_mar(SRC, T1)) != (void*)0)
return(error_message);
// t1 < (mar)
if((error_message = mar_indirect_to_reg(T1)) != (void*)0)
return(error_message);
// dst < dst - 1
if((error_message = dec_reg(DST)) != (void*)0)
return(error_message);
// (dst) < t1
if((error_message = reg_to_reg_indirect(T1, DST)) != (void*)0)
return(error_message);
if(trace_flag)
{
mnemonic+="[";
mnemonic+=data_path.register_set.GetRegisterData(SRC).name;
mnemonic+=",$";
mnemonic+=IntToString(index, 4);
mnemonic+="]";
}
}
if(trace_flag)
{
mnemonic+=",";
mnemonic+=data_path.register_set.GetRegisterData(DST).name;
}
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// set_carry - SEC
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteSEC(int trace_flag)
{
unsigned long flag;
flag = (data_path.alu.GetFlags()) | C_FLAG;
data_path.alu.SetFlags(flag);
return(data_path.Clock());
}
///////////////////////////////////////////////////////////////////////////////
// clear_carry - CLC
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteCLC(int trace_flag)
{
unsigned long flag;
flag = (data_path.alu.GetFlags()) & (~C_FLAG);
data_path.alu.SetFlags(flag);
return(data_path.Clock());
}
///////////////////////////////////////////////////////////////////////////////
// set_interrupt - SEI
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteSEI(int trace_flag)
{
unsigned long flag;
flag = (data_path.alu.GetFlags()) | I_FLAG;
data_path.alu.SetFlags(flag);
return(data_path.Clock());
}
///////////////////////////////////////////////////////////////////////////////
// clear_interrupt - CLI
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteCLI(int trace_flag)
{
unsigned long flag;
flag = (data_path.alu.GetFlags()) & (~I_FLAG);
data_path.alu.SetFlags(flag);
return(data_path.Clock());
}
///////////////////////////////////////////////////////////////////////////////
// ret_from_int - RTI
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteRTI(int trace_flag)
{
const char* error_message;
// pc < (sp)
if((error_message = reg_indirect_to_reg(SP, PC)) != (void*)0)
return(error_message);
// sp < sp + 1
if((error_message = inc_reg(SP)) != (void*)0)
return(error_message);
// t1 < (sp)
if((error_message = reg_indirect_to_reg(SP, T1)) != (void*)0)
return(error_message);
// sp < sp + 1
if((error_message = inc_reg(SP)) != (void*)0)
return(error_message);
// flags < t1
if((error_message = reg_to_flags(T1)) != (void*)0)
return(error_message);
return((void*)0);
}
///////////////////////////////////////////////////////////////////////////////
// software_int - SWI
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteSWI(int trace_flag)
{
const char* error_message;
// t1 < swireg
if((error_message = reg_to_reg(SWI, T1)) != (void*)0)
return(error_message);
// sp < sp - 1
if((error_message = dec_reg(SP)) != (void*)0)
return(error_message);
// t2 < flags
if((error_message = flags_to_reg(T2)) != (void*)0)
return(error_message);
// (sp) < t2; sp < sp - 1
if((error_message = reg_to_reg_indirect_with_dec(T2, SP)) != (void*)0)
return(error_message);
// (sp) < pc
if((error_message = reg_to_reg_indirect(PC, SP)) != (void*)0)
return(error_message);
// pc < t1
if((error_message = reg_to_reg(T1, PC)) != (void*)0)
return(error_message);
// sei
return(ExecuteSEI(trace_flag));
}
///////////////////////////////////////////////////////////////////////////////
// exchange - EXCH - this instruction has not been implemented in the
// simulator
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteEXCH(int trace_flag)
{
return("Not Implemented");
}
///////////////////////////////////////////////////////////////////////////////
// search - SRCH - this instruction has not been implemented in the
// simulator
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteSRCH(int trace_flag)
{
return("Not Implemented");
}